package eerbaar.v2.pattern.client.internal.teach;

import javax.swing.JOptionPane;

import eerbaar.game.IGame;
import eerbaar.memory.IMemory;
import eerbaar.message.lib.DisplayRisingTextMsg;
import eerbaar.message.lib.NotifyCommandCreatedMsg;
import eerbaar.message.lib.TeachingStartedMsg;
import eerbaar.message.lib.TeachingStoppedMsg;
import eerbaar.persona.IPersona;
import eerbaar.position.IPosition;
import eerbaar.shared.message.MsgHelper;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.NodeCmdFactory;
import eerbaar.shared.tree.NodeFactory;
import eerbaar.v2.app.GameHelper;
import eerbaar.v2.app.menu.IMenuProvider;
import eerbaar.v2.app.menu.IMenuService;
import eerbaar.v2.menu.MenuItem;
import eerbaar.v2.pattern.client.internal.FreePlayMenu;
import eerbaar.v2.pattern.client.internal.ProgramNameGenerator;

public class TeachingMediator {

    public static TeachingMediator getInstance() {
        return instance;
    }

    private String lastProgram;
    // private final TeachingDisplay teachingDisplay;
    private TeachingState state = TeachingState.WAITING_TO_TEACH;
    private static MenuItem freePlayMenu = new FreePlayMenu();

    // private final ProgramWidget programWidget;

    private static final TeachingMediator instance = new TeachingMediator();

    public TeachingMediator() {
        // this.teachingDisplay = new TeachingDisplay();
        // this.dialog = new TeachingDialog(this);
        // this.programWidget = programWidget;
        init();
    }

    public void addFreePlayMenu() {

        IMenuService service = ServiceFactory.getService(IMenuService.class);
        IMenuProvider provider = service.get("petMenu");

        provider.addMenuItem(freePlayMenu);
    }

    private void generateGame() {

        ProgramNameGenerator g = new ProgramNameGenerator();
        String name = g.getPrefered(this.lastProgram);
        if (name == null) {

            JOptionPane.showMessageDialog(null, this.lastProgram);
            // this.dialog.display();
        } else {
            IGame game = GameHelper.getGame();
            IPersona pet = game.getPersona("pet");
            IPosition p = pet.getPosition();

            MsgHelper.sendMsg(DisplayRisingTextMsg.class,
                    new DisplayRisingTextMsg("Command", p.getX(), p.getY(),
                            eerbaar.commons.Color.BLUE));
            onProgramName(name);
        }

    }

    public String getLastProgram() {
        return this.lastProgram;
    }

    public TeachingState getState() {
        return this.state;
    }

    private void init() {

        TeachingMessageReader reader = new TeachingMessageReader(this);
        reader.registerReaders();
    }

    public void onNewProgram(String program) {

        if (program != null) {

            this.lastProgram = program;
            addFreePlayMenu();
            setState(TeachingState.INPUTING_NAME);
        } else {

            setState(TeachingState.WAITING_TO_TEACH);
        }
    }

    public void onNoProgram() {

        // this.dialog.displayFail();
        setState(TeachingState.WAITING_TO_TEACH);
    }

    public void onProgramName(String name) {

        if (this.lastProgram == null) {
            return;
        }

        setState(TeachingState.WAITING_TO_TEACH);
        saveProgram(name, this.lastProgram);
        this.lastProgram = null;
        // this.programWidget.displayCommands();

        MsgHelper.sendMsg(NotifyCommandCreatedMsg.class,
                new NotifyCommandCreatedMsg());
    }

    public void removeFreePlayMenu() {

        IMenuService service = ServiceFactory.getService(IMenuService.class);
        IMenuProvider provider = service.get("petMenu");

        provider.removeMenuItem(freePlayMenu);
    }

    private void saveProgram(String name, String program) {

        IGame game = GameHelper.getGame();

        IPersona pet = game.getPersona("pet");
        IMemory memory = pet.getHead().getBrain().getMemory();

        INode commandNode = memory.getCommandsNode();
        INode test = NodeCmdFactory.findChild(commandNode, name);
        if (test == null) {

            INode cmdNode = NodeFactory.create(name);
            commandNode.add(cmdNode);

            INode ideaNode = memory.getIdeaNode();
            INode programNode = NodeFactory.create(name, program);
            ideaNode.add(programNode);
        }
    }

    public void setState(TeachingState state) {

        switch (state) {
        case WAITING_TO_TEACH:
            // this.teachingDisplay.displayStartTeaching();
            MsgHelper.sendMsg(TeachingStoppedMsg.class,
                    new TeachingStoppedMsg());
            break;
        case TEACHING:
            // this.teachingDisplay.displayFinishTeaching();
            MsgHelper.sendMsg(TeachingStartedMsg.class,
                    new TeachingStartedMsg());
            break;
        case INPUTING_NAME:
            generateGame();
            break;
        case WAITING_FOR_SERVER:
            MsgHelper.sendMsg(TeachingStoppedMsg.class,
                    new TeachingStoppedMsg());
            break;
        }

        // this.programWidget.displayCommands();
        this.state = state;
    }

}
